<template>
<!--
      van-list自带上拉加载更多 的效果
      原理：
        1）数据项在list中
        2）在显示数据时，如果当前的数据不足一屏，它会 自动调用 onLoad去加载数据
           在onload是要通过ajax取回新数据
           - 把数据追加到list中（list的内容会越来越多）
           - 把loading手动设置为false
           - 判断是否所有的数据已经加载完成，如果是，则把finished设为true
        3) 如果手动向上拉，且finished不为true, 也会去调用onLoad
    -->
    <!-- scroll-wrapper  这个在全局 index.less 中   不要写错了 -->
    <!-- 它的目标：显示它对应的那个频道下的文章信息
  为了达到从文章详情页回到列表时，能还原它的滚动条的位置：
  1. 在组件内监听scroll，实时记录这个位置
  2. 再次回到本组件（从文章详情页回来），去恢复滚动条的位置

  如果这个组件被缓存了，则它会多个两个特殊的钩子函数
   activated() {}    激活
   deactivated () {} 失活
-->
  <div class="scroll-wrapper" @scroll="hScroll" ref="refScroll">
    <van-pull-refresh v-model="isLoadingNew" @refresh="onRefresh">
         <van-list
            v-model="loading"
            :finished="finished"
            finished-text="没有更多了"
            @load="onLoad"
        >
            <van-cell
            v-for="(item,idx) in list"
            :key="idx"
            :title="item.title"
            @click="$router.push('/article/' + item.art_id.toString())">
            <div slot="label">
            <!-- 图片 当前文章有几张图 就用几个宫格 -->
            <!-- :border="false"  清除边框线 -->
            <van-grid :column-num="item.cover.images.length" :border="false">
                <van-grid-item v-for="(img,idx) in item.cover.images" :key="idx">
                <van-image lazy-load :src="img" />
                </van-grid-item>
            </van-grid>

            <!-- 文字说明 -->
            <div class="meta">
                <span>{{item.aut_name}}</span>
                <span>{{item.comm_count}}评论</span>
                <!-- 使用过滤器 -->
                <span>{{item.pubdate | formatTime}}</span>
                <span>{{item.pubdate | relativeTime}}</span>
                <!-- 如果登陆用户，则显示x按钮
                    如何知道当前用户是否登陆？ 去vuex中查看，是否有token
                -->
                <span class="close" v-if="$store.state.tokenInfo.token" @click.stop="hClose(item)">
                  <van-icon name="cross"></van-icon>
                </span>
            </div>

            </div>
        </van-cell>
        </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
import { getArticles } from '@/api/article.js'
export default {
  name: 'ArticleList',
  // 从父组件中获取的频道信息
  props: ['channel'],
  data () {
    return {
      list: [], // 数据,每一项就是一篇文章
      timestamp: null,
      isLoadingNew: false, // 是否下拉刷新。。。
      loading: false, // 是否正在加载
      finished: false // 是否所有的数据全部加载完成
    }
  },
  created () {
    // console.log(this.channel, 'created,启动了监听')
    this.$eventBus.$on('delArticle', (obj) => {
      const { articleId, channelId } = obj
      // console.log('我这里是', this.channel, '收到了事件', obj)
      // todo: 是否需要在本文章列表中去删除对应的数据
      // 是否是当前频道：
      // 是： 在list中找到编号是obj.articleId的数据，并删除
      // 否 ： 不处理
      if (channelId !== this.channel.id) {
        // console.log('你要删除的文章不在我这' + this.channel.name + '上')
        return
      }
      // console.log(`list中找到编号是${obj.articleId}的数据，并删除`)
      // 在list中找到编号是obj.articleId的数据，并删除
      // 在数组中找一个元素，并删除
      // 1.找下标
      // 2.做删除
      // findIndex() 方法返回传入一个测试条件（函数）符合条件的数组第一个元素位置。

      // findIndex() 方法为数组中的每个元素都调用一次函数执行：

      // 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置，之后的值不会再调用执行函数。
      // 如果没有符合条件的元素返回 -1
      // 注意: findIndex() 对于空数组，函数是不会执行的。

      // 注意: findIndex() 并没有改变数组的原始值。
      const idx = this.list.findIndex(article => {
        return article.art_id.toString() === articleId
      })
      if (idx !== -1) {
        // 找到元素
        // 如何在数组中，删除指定下标的元素？
        // splice() 方法向/从数组中添加/删除项目，然后返回被删除的项目。
        // 注释：该方法会改变原始数组。
        // 语法
        // arrayObject.splice(index,howmany,item1,.....,itemX)
        this.list.splice(idx, 1)
      }
    })
  },
  methods: {
    hScroll () {
      console.log(this.$refs.refScroll.scrollTop)
      this.scrollTop = this.$refs.refScroll.scrollTop
    },
    // 点击关闭按钮，通知父组件index.vue中去显示更多操作的弹层
    hClose (article) {
      // 它向父组件index.vue抛出一个事件
      this.$emit('showMoreAction', article.art_id.toString())
    },
    //  下拉刷新
    async onRefresh () {
      // 1.取会最新的文章，传入最新的时间戳
      const result = await getArticles(this.channel.id, Date.now())
      //   2.把文章追加到 list的头部
      const arr = result.data.data.results
      this.list.unshift(...arr)
      this.$toast.success('刷新成功' + arr.length + '条')
      // 3.结束loading状态
      this.isLoadingNew = false
    },
    async onLoad () {
    // 异步更新数据
    // setTimeout 仅做示例，真实场景中一般为 ajax 请求
      if (!this.timestamp) {
        this.timestamp = Date.now()
      }
      // 1.发请求
      const result = await getArticles(this.channel.id, this.timestamp)
      //   console.log(result)
      // 保存本次请求回来的数据中携带的时间戳，以便下传请求再传入
      this.timestamp = result.data.data.pre_timestamp
      const arr = result.data.data.results
      // 2. 把数据添加到list中去
      // 把10条数据追加到数据中去
      this.list.push(...arr)
      // 3. 加载状态结束
      this.loading = false
      // 4. 是否全部加载完成
      if (arr.length === 0) {
        this.finished = true
      }
    }
  },
  //   如果这个组件被缓存了，则它会多个两个特殊的钩子函数
  //  activated() {}    激活
  //  deactivated () {} 失活
  activated () {
    if (this.scrollTop) {
      this.$refs.refScroll.scrollTop = this.scrollTop
    }
  },
  deactivated () {
    console.log('失去滚动')
  }
}
</script>

<style lang="less" scoped>
.meta {
  display:flex;
  span {
    margin-right:10px;
  }
  .close{
    // 让它在最右边
    // 它的父级容器是flex的，给当前元素设置左外边距为auto，会让这个元素在父级容器
    // 的最右边
    margin-left:auto;
  }
}
</style>
